/*
 *  This file is part of WWWPal.
 *
 *  Copyright (C) 2003  Dr. John Punin, Department of Computer Science
 *  Rensselaer Polytechnic Institute
 *
 *  WWWPal is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  WWWPal is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Foobar; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "client.h"
#include "partition.h"
#include <rep_blinks.h>
#include <rep_title.h>
#include <rep_general.h>
#include "webdir.h"
#include "second_part.h"
#include "report_map.h"
#include "third_part.h"
#include "dirpartition.h"
#include <gr_xmlparser.h>
#include <gr_xmlwrite.h>

int
main(int argc, char *argv[])
{
  mainFrame *mf = new_main_frame();
  assert(mf != NULL);

  if(read_command_line(mf,argc,argv))
    {
      print_options(mf);
      delete_main_frame(mf);
    }
  return 0;
}

void
delete_main_frame(mainFrame *mf)
{
  LNode_type *ptr;

  if(mf->ltgr_frame)
    {
      for(ptr = mf->ltgr_frame->back; ptr != mf->ltgr_frame ; ptr = ptr->back)
	{
	  tgrFrame *tgf = (tgrFrame *) ptr->info;
	  if(tgf)
	    delete_tgr_frame(tgf);
	}
    }
  
  if(mf->ltgr_frame)
    Delete_all_list(mf->ltgr_frame);
  if(mf->basename) {
      free(mf->basename); mf->basename = NULL;
  }
  free(mf); mf = NULL;
}

mainFrame *
new_main_frame(void)
{
  GraphFrame *gf = create_current_graph();
  tgrFrame *tgf = (gf ? new_tgr_frame(gf) : NULL);
  mainFrame *mf = (mainFrame *)calloc(1, sizeof(mainFrame));
  if(!mf) {
      fprintf(stderr,"Out of Memory new_main_frame\n");
      abort();
  }
  init_graph(gf);
  mf->cur = 0;
  mf->nroot = NULL;
  mf->ltgr_frame = init_linked_list();  
  mf->findex = 0;
  
  if(tgf)
    {
      Insert_linked_list(mf->ltgr_frame, create_new_node_llist((char *)tgf));
      mf->cur_node_tgf = mf->ltgr_frame->back;
    }
  return mf;
}

int
read_command_line(mainFrame *mf, int argc, char *argv[])
{
  char *filename = NULL;
  char *text;
  int mes;

  tgrFrame *tgf = (tgrFrame *)mf->cur_node_tgf->info;

  GraphFrame *gf = tgf->gf;

  if(argc == 2)
      GRStrAllocCopy(filename,argv[1]);
  else if(argc == 1)
    {
      filename = malloc(FLINE);
      if(!filename) {
	  fprintf(stderr,"Out of Memory read_command_line\n");
	  abort();
      }
      printf("Name of the graph File: ");
      scanf("%s",filename);
    }
  else
    {
      fprintf(stderr,"No more than 2 arguments\n");
      return 0;
    }

  if(!read_regular_file(filename, &text))
    {
      long len = strlen(text);
      GRStrAllocCopy(tgf->filename,filename);
      tgf->saved = 1;
      mf->basename = get_base_name(filename);
      
      if(mf->basename)
	printf("Basename is %s\n", mf->basename);
      else
	printf("No base name\n");

      if((mes = parse_xml_text_graph(gf,text,len)))
	{
	  if(mes < 0)
	    fprintf(stderr,"Graph File is wrong\n");
	}
      else
        {
	  if(get_graphic_flag(gf)!=GRAPHIC_ON)
	      set_shape_from_attributes(gf);
	}	
      tgf->root = get_root_vertex(gf);
      if(!tgf->root)
	  tgf->root = find_vertex_by_number(gf,1); /* First vertex */
      if(!tgf->root)
	  tgf->root = find_vertex_by_number(gf,2); /* Second vertex */
      
    }
  free(text); text = NULL;
  free(filename); filename = NULL;
  /*fclose(fp);*/
  return 1;
}


void
print_options(mainFrame *mf)
{
  int option;
  while(1)
    {
      option = 0;
      printf("\nChoose one option: \n");
      printf("1. Draw Circular\n");
      printf("2. Draw Horizontal\n");
      printf("3. Draw Diagonal\n");
      printf("4. Draw Random\n");
      printf("5. Draw Pretty\n");
      printf("6. Draw Pretty Initial\n");
      printf("7. Draw Tree ...\n");
      printf("8. Draw Hor. Tree ...\n");
      printf("9. Draw Radial Tree ...\n");
      printf("10. Draw Level\n");
      printf("11. Draw Barycentric ...\n");
      printf("12. Save file as ...\n");
      printf("13. Print Node Positions\n");
      printf("14. Print Selected Nodes\n");
      printf("15. Select/Deselect ...\n");
      printf("16. Select All\n");
      printf("17. Select by Name ...\n");
      printf("18. Select by Children ...\n");
      printf("19. Select by Tree ...\n");
      printf("20. Deselect All\n");
      printf("21. DFS or BFS Tree ...\n");
      printf("22. Browser\n");
      printf("23. Group\n");
      printf("24. Choose Graph ...\n");
      printf("25. Delete Graph ...\n");
      printf("26. First Partition Algorithm ...\n");
      printf("27. Report Pages with Broken Links ...\n");
      printf("28. Construct Web Directory ...\n");
      printf("29. Select by Tree template ...\n");
      printf("30. Second Partition Algorithm ...\n");
      printf("31. Report Site Map ...\n");
      printf("32. Third Partition Algorithm ...\n");
      printf("33. Report Broken Objects ...\n");
      printf("34. Reduce Graph\n");
      printf("35. Compute Graph Clusters\n");
      printf("36. Dir Partition Algorithm\n");
      printf("37. Generate Line Graph\n");
      printf("38. Report Broken Links ...\n");
      printf("39. Report Pages without Title ...\n");
      printf("40. Report of Orphan Pages ...\n");
      printf("41. Report of Images without ALT ...\n");
      printf("42. Report of Pages with Images without ALT ...\n");
      printf("43. Report of Hyperlinks ...\n");
      printf("44. Report of Pages ...\n");
      printf("45. Report of Web Graph ...\n");
      printf("46. Report of Biggest Pages ...\n");
      printf("47. Report of Pages with Highest References...\n");
      printf("48. Generate Index of Reports...\n");
      printf("49. Matrix of Shortest Path...\n");
      printf("50. Compute Cluster Coefficient...\n");
      printf("51. Report Hierarchical Tree...\n");
      printf("99. Quit\n\n");
      printf("Option -> ");
      scanf("%d",&option);
      if(option == 0)
	getchar();
      if(option > 0 && option < 99)
	execute_option(mf,option);
      else if(option == 99)
	break;
      else
	printf("try again");
    }
}

void
execute_option(mainFrame *mf, int option)
{
  int mes=0;
  tgrFrame *tgf = (tgrFrame *)mf->cur_node_tgf->info;
  GraphFrame *gf = tgf->gf;

  tgf->saved = 0;

  switch(option)
    {
    case 1:
      mes = compute_circular_positions(gf);
      break;
    case 2:
      mes = compute_horizontal_positions(gf);
      break;
    case 3:
      mes = compute_diagonal_positions(gf);
      break;
    case 4:
      mes = compute_random_positions(gf);
      break;
    case 5:
      mes = compute_pretty_positions(gf,False);
      break;
    case 6:
      mes = compute_pretty_positions(gf,True);
      break;
    case 7:
      mes = execute_tree(gf,0);
      break;
    case 8:
      mes = execute_tree(gf,1);
      break;
    case 9:
      mes = execute_tree(gf,2);
      break;
    case 10:
      mes = compute_level_positions(gf);
      break;
    case 11:
      mes = execute_barycentric(gf);
      break;
    case 12:
      mes = save_current_graph(tgf);
      break;
    case 13:
      print_nodes(gf);
      break;
    case 14:
      print_selected_nodes(gf);
      break;
    case 15:
      execute_select(gf,0);
      break;
    case 16:
      execute_select(gf,1);
      break;
    case 17:
      execute_select(gf,2);
      break;
    case 18:
      execute_select(gf,3);
      break;
    case 19:
      execute_select(gf,4);
      break;
    case 20:
      execute_select(gf,5);
      break;
    case 21:
      ask_method_tree(gf);
      break;
    case 22:
      execute_browsing(mf);
      break;
    case 23:
      execute_grouping(mf);
      break;
    case 24:
      choose_graph(mf);
      break;
    case 25:
      delete_one_graph(mf);
      break;
    case 26:
      execute_first_partition(mf);
      break;
    case 27:
      execute_pages_broken_links(mf);
      break;
    case 28:
      execute_web_directory(mf);
      break;
    case 29:
      execute_select(gf,6);
      break;
    case 30:
      execute_second_partition(mf);
      break;
    case 31:
      execute_site_map(mf);
      break;
    case 32:
      execute_third_partition(mf);
      break;
    case 33:
      execute_broken_objects(mf);
      break;
    case 34:
      execute_reduce_graph(mf);
      break;
    case 35:
      execute_graph_clusters(mf);
      break;
    case 36:
	/*execute_dir_clustering(mf);*/
      execute_dir_partition(mf);
      break;
    case 37:
      execute_line_graph(mf);
      break;
    case 38:
      execute_broken_links(mf);
      break;
    case 39:
      execute_pages_without_title(mf);
      break;
    case 40:
      execute_orphan_pages(mf);
      break;
    case 41:
      execute_images_no_alt(mf);
      break;
    case 42:
      execute_pages_images_no_alt(mf);
      break;
    case 43:
      execute_report_hyperlinks(mf);
      break;
    case 44:
      execute_report_pages(mf);
      break;
    case 45:
      execute_report_webgraph(mf);
      break;
    case 46:
      execute_biggest_pages(mf);
      break;
    case 47:
      execute_references_pages(mf);
      break;
    case 48:
      generate_index_reports(mf);
      break;
    case 49:
      generate_matrix_shortest_paths(mf);
      break;
    case 50:
      execute_compute_cluster_coefficient(mf);
      break;
    case 51:
      execute_report_hierarchical_tree(mf);
      break;
    }

  if(mes < 0)
    fprintf(stderr,"Something was wrong: %d\n",mes);
  
}

int 
choose_graph(mainFrame *mf)
{
  LNode_type *ptr = mf->ltgr_frame->back;
  int i=0,ig=0;
  int ifg = count_llist(mf->ltgr_frame)-1;

  printf("Current Graph is %d\n",mf->cur);
  printf("Choose Graphs between (0..%d) -> ",ifg);
  scanf("%d", &ig);

  if(ig < 0 || ig > ifg)
    {
      printf("Graph %d was not found \n", ig);
      return 0;
    }
  
  for(;ptr != mf->ltgr_frame; ptr = ptr->back)
    {
      if(i == ig)
	{
	  mf->cur = i;
	  mf->cur_node_tgf = ptr;
	  return 1;
	}
      i++;
    }
  printf("Graph %d was not found \n", ig);
  return 0;
}

tgrFrame *
execute_grouping(mainFrame *mf)
{
  tgrFrame *tgf = (tgrFrame *)mf->cur_node_tgf->info;
  GraphFrame *gf = tgf->gf;

  GraphFrame *ngf = create_current_graph();
  tgrFrame *ntgf = new_tgr_frame(ngf);

  init_graph(ngf);
  
  set_graph_dir(ngf,get_graph_dir(gf));
  set_num_ver_group(ngf,get_num_ver_group(gf));
  set_num_vertex(ngf,get_num_vertex(gf));
  set_dim_vertex(ngf,get_ver_size(gf),get_hor_size(gf));
  set_scale(ngf,get_scale(gf));
  set_dimensions(ngf,gf->w, gf->h);

  /*grouping_selected_nodes(ngf,gf);*/
  extended_grouping_selected_nodes(ngf,gf);
  Insert_linked_list(mf->ltgr_frame, create_new_node_llist((char *)ntgf));
  return ntgf;
}

tgrFrame *
execute_browsing(mainFrame *mf)
{
  tgrFrame *tgf = (tgrFrame *)mf->cur_node_tgf->info;
  GraphFrame *gf = tgf->gf;

  GraphFrame *ngf = create_current_graph();
  tgrFrame *ntgf = new_tgr_frame(ngf);

  init_graph(ngf);

  set_graph_dir(ngf,get_graph_dir(gf));
  set_num_ver_group(ngf,get_num_ver_group(gf));
  set_num_vertex(ngf,get_num_vertex(gf));
  set_dim_vertex(ngf,get_ver_size(gf),get_hor_size(gf));
  set_scale(ngf,get_scale(gf));
  set_dimensions(ngf,gf->w, gf->h);

  /*insert_selected_nodes(ngf,gf);*/
  extended_browsing(ngf,gf);
  
  Insert_linked_list(mf->ltgr_frame, create_new_node_llist((char *)ntgf));
  return ntgf;
}

tgrFrame *
execute_simple_browsing(mainFrame *mf)
{
  tgrFrame *tgf = (tgrFrame *)mf->cur_node_tgf->info;
  GraphFrame *gf = tgf->gf;

  GraphFrame *ngf = create_current_graph();
  tgrFrame *ntgf = new_tgr_frame(ngf);

  init_graph(ngf);

  set_graph_dir(ngf,get_graph_dir(gf));
  set_num_ver_group(ngf,get_num_ver_group(gf));
  set_num_vertex(ngf,get_num_vertex(gf));
  set_dim_vertex(ngf,get_ver_size(gf),get_hor_size(gf));
  set_scale(ngf,get_scale(gf));
  set_dimensions(ngf,gf->w, gf->h);

  insert_selected_nodes(ngf,gf);
  
  Insert_linked_list(mf->ltgr_frame, create_new_node_llist((char *)ntgf));
  return ntgf;
}

tgrFrame *
execute_reduce_graph(mainFrame *mf)
{
  tgrFrame *tgf = (tgrFrame *)mf->cur_node_tgf->info;
  GraphFrame *gf = tgf->gf;
  GraphFrame *ngf; 
  tgrFrame *ntgf; 
  LNode_type *leqnodes = get_list_of_equivalent_nodes(gf);

  if(leqnodes == NULL)
    {
      printf("Graph is not reducible\n");
      return NULL;
    }
  ngf = create_current_graph();
  ntgf = new_tgr_frame(ngf);
  init_graph(ngf);
  
  set_graph_dir(ngf,get_graph_dir(gf));
  set_num_ver_group(ngf,get_num_ver_group(gf));
  set_num_vertex(ngf,get_num_vertex(gf));
  set_dim_vertex(ngf,get_ver_size(gf),get_hor_size(gf));
  set_scale(ngf,get_scale(gf));
  set_dimensions(ngf,gf->w, gf->h);
  reduce_graph_with_equivalent_nodes(gf, ngf, leqnodes);
  Delete_all_list(leqnodes);

  Insert_linked_list(mf->ltgr_frame, create_new_node_llist((char *)ntgf));
  return ntgf;
}

void
execute_graph_clusters(mainFrame *mf)
{
  tgrFrame *tgf = (tgrFrame *)mf->cur_node_tgf->info;
  GraphFrame *gf = tgf->gf;
  int num_clusters = 1;
  printf("\nNumber of Clusters : ");
  scanf("%d", &num_clusters);
  compute_clusters(gf,num_clusters);
}

int
execute_tree(GraphFrame *gf,int type_tree)
{
  int vnum=0;
  struct pt *v;
  int mes = -1;

  printf("\nNumber of the Root Vertex : ");
  scanf("%d", &vnum);

  v = find_vertex_by_number(gf,vnum);
  if(v)
    {
      switch(type_tree)
	{
	case 0:
	  mes = compute_tree_positions(gf,v,NORTH);
	  break;
	case 1:
	  mes = compute_tree_positions(gf,v,EAST);
	  break;
	case 2:
	  mes = compute_radial_positions(gf,v);
	  break;
	}
    }
  else
    printf("Vertex %d was not found\n", vnum);
  return mes;
}


int
execute_barycentric(GraphFrame *gf)
{
  int clen;
  int mes = -1;

  printf("\n Cycle Length : ");
  scanf("%d", &clen);

  if(clen > 2)
    mes = compute_bary_positions(gf,clen);
  return mes;
}

void
init_graph(GraphFrame *gf)
{
  set_dimensions(gf, WIDTH, HEIGHT);
  set_show_vertex_weight(gf, False);
  set_show_edge_weight(gf, False);
  set_shape(gf, BOX);
  set_dim_vertex(gf,BSIDE,HSIDE);
  set_scale(gf, 0);
  set_flag_draw(gf, True);
  set_num_vertex(gf, 0);
  set_num_ver_group(gf, 0);
  set_count_vertex(gf,0);
  set_method_tree(gf,BFS_TREE);
  set_graph_dir(gf, NONE);
}


void 
print_nodes(GraphFrame *gf)
{
  LNode_type *ptr,*lver = get_list_vertices(gf);
  for(ptr = lver->back; ptr != lver; ptr= ptr->back)
    {
      struct pt *v = (struct pt *)ptr->info;
      printf("%d :(%d, %d) \"%s\"\n", get_vertex_number(v), get_x(v), 
	     get_y(v),get_label_vertex(v));
    }
  printf("Graph has %d vertices\n", get_count_vertex(gf));
}
void 
print_selected_nodes(GraphFrame *gf)
{
  LNode_type *ptr,*lver = get_list_selected_vertices(gf);
  ptr = lver->back;

  if(ptr == lver)
    printf("No Selected Nodes\n");

  for(; ptr != lver; ptr= ptr->back)
    {
      struct pt *v = (struct pt *)ptr->info;
      printf("%d :\"%s\"\n", get_vertex_number(v),get_label_vertex(v));
    }
}

int 
read_regular_file(char *filename, char **stext)
{
  char *text;
  struct stat statb;
  FILE *fp;

  *stext = NULL;

  /* make sure the file is a regular text file and open it */
  if(stat(filename, &statb) == -1 ||
     (statb.st_mode & S_IFMT ) != S_IFREG ||
     !(fp = fopen(filename, "r"))) 
    {
      if((statb.st_mode & S_IFMT) == S_IFREG)
	perror(filename);
      else
	fprintf(stderr, "%s : not a regular file \n", filename);
      free(filename); filename = NULL;
      return -1;
    }

  if(!(text = malloc((unsigned)(statb.st_size +1))))
    {
      fprintf(stderr, "Can't alloc enough space for %s", filename);
      free(filename); filename = NULL;
      fclose(fp);
      abort();
    }
  if(!fread(text,sizeof(char), statb.st_size + 1, fp))
    fprintf(stderr, "Warning: may not have read entire file!\n");
  text[statb.st_size] = 0; /* be sure to NULL-terminate */
  *stext = text;
  fclose(fp);
  return 0;
}

void
execute_select(GraphFrame *gf, int case_select)
{
  int vnum=1, icount=0;
  struct pt *v=NULL;
  char str[1024];
  switch(case_select)
    {
    case 0:
      printf("Vertex Number -> ");
      scanf("%d", &vnum);
      v = find_vertex_by_number(gf,vnum);
      if(v)
	{
	  change_selection_vertex(gf, v,!(v->select));
	  printf("Vertex %d:%s changed selection\n", v->num, v->label);
	}
      else
	printf("Vertex %d was not found\n", vnum);
      break;
    case 1:
      select_all_nodes(gf);
      printf("%d Vertices has been selected\n", get_count_vertex(gf));
      break;
    case 2:
      printf("String Template : ");
      scanf("%s",str);
      icount = select_nodes_by_string_template(gf, str);
      printf("%d Vertices has been selected\n", icount);
      break;
    case 3:
      printf("Vertex Number -> ");
      scanf("%d", &vnum);
      v = find_vertex_by_number(gf,vnum);
      if(v)
	{
	  icount = select_immediate_children(gf, v);
	  printf("%d Vertices has been selected\n", icount);
	}      
      else
	printf("Vertex %d was not found\n", vnum);
      break;
    case 4:
      printf("Vertex Number -> ");
      scanf("%d", &vnum);
      v = find_vertex_by_number(gf,vnum);
      if(v)
	{
	  icount = select_tree(gf, v);
	  printf("%d Vertices has been selected\n", icount);
	}      
      else
	printf("Vertex %d was not found\n", vnum);
      break;
    case 5:
      deselect_all_nodes(gf);
      printf("%d Vertices has been deselected\n", get_count_vertex(gf));
      break;
    case 6:
      printf("Vertex Number -> ");
      scanf("%d", &vnum);
      v = find_vertex_by_number(gf,vnum);
      if(v)
	{
	  icount = select_tree_by_template(gf, v);
	  printf("%d Vertices has been selected\n", icount);
	}      
      else
	printf("Vertex %d was not found\n", vnum);
      break;
    }
}

void
ask_method_tree(GraphFrame *gf)
{
  int option=0;
  printf("Tree method : 0 (DFS) or 1 (BFS) -> ");
  scanf("%d",&option);
  if(option == 1)
    {
      set_method_tree(gf, BFS_TREE);
      printf("BFS TREE\n");
    }
  else
    {
      set_method_tree(gf, BFS_TREE);
      printf("DFS TREE\n");
    }
}

int
delete_one_graph(mainFrame *mf)
{
  tgrFrame *tgf = (tgrFrame *)mf->cur_node_tgf->info;
  char si;
  int count = count_llist(mf->ltgr_frame);
  
  if(count == 1)
    {
      printf("Sorry, there is only one graph\n");
      return 0;
    }
  printf("Are you sure you want to delete Graph %d ? (y/n) ", mf->cur);
  scanf("%c",&si);
  scanf("%c",&si);

  if(si == 'y')
    {
      if(tgf->saved == 0)
	{
	  printf(
	     "Graph %d has not been saved, Do you want to delete it ? (y/n) ", 
	     mf->cur);
	  
	  scanf("%c", &si);
	  scanf("%c",&si);
	  if(si == 'y')
	    {
	      printf("Graph %d was deleted", mf->cur);
	      Delete_linked_list(mf->cur_node_tgf);
	      mf->cur =0;
	      mf->cur_node_tgf = mf->ltgr_frame->back;
	      delete_tgr_frame(tgf);
	      return 1;
	    }
	}
      else
	{
	  printf("Graph %d was deleted", mf->cur);
	  Delete_linked_list(mf->cur_node_tgf);
	  mf->cur =0;
	  mf->cur_node_tgf = mf->ltgr_frame->back;
	  delete_tgr_frame(tgf);
	  return 1;
	}
    }
  return 0;
}


char *
get_base_name(char *filename)
{
  int i = 0;
  int len = strlen(filename);
  int start=0, end=len;

  for(i = len - 1; i >= 0 ; i--)
    {
      if(filename[i]=='.')
	{
	  end = i;
	  break;
	}
      
    }
  for(i = len - 1; i >= 0 ; i--)
    {
      if(filename[i]=='/')
	{
	  start = i+1;
	  break;
	}
    }

  if(end > start)
    {
      int j=0;
      char *tstr = (char *)malloc((end - start + 2)* sizeof(char));
      if(!tstr) {
	  fprintf(stderr,"Out of Memory get_base_name\n");
	  abort();
      }
      for(i= start ; i < end ;i++)
	{
	  tstr[j++] = filename[i];
	}
      tstr[j] = '\0';
      return tstr;
    }
  return NULL;
}


void
execute_orphan_pages(mainFrame *mf)
{
  tgrFrame *tgf = (tgrFrame *)mf->cur_node_tgf->info;
  char * filename = malloc(50);
  if(!filename) {
      fprintf(stderr,"Out of Memory execute_orphan_pages\n");
      abort();
  }

  printf("HTML File Name for report of orphan pages :");
  scanf("%s", filename);
  report_ord_orphan_pages(tgf->gf, filename);
  free(filename); filename = NULL;
}

void
execute_report_webgraph(mainFrame *mf)
{
  tgrFrame *tgf = (tgrFrame *)mf->cur_node_tgf->info;
  char * filename = malloc(50);
  if(!filename) {
      fprintf(stderr,"Out of Memory execute_report_webgraph\n");
      abort();
  }

  printf("HTML File Name for report of Web Graph :");
  scanf("%s", filename);
  report_webgraph_summary(tgf->gf, filename);
  free(filename); filename = NULL;
}

void
execute_biggest_pages(mainFrame *mf)
{
  tgrFrame *tgf = (tgrFrame *)mf->cur_node_tgf->info;
  char * filename = malloc(50);
  int npages = 0;
  if(!filename) {
      fprintf(stderr,"Out of Memory execute_biggest_pages\n");
      abort();
  }

  printf("HTML File Name for report of Biggest Pages  :");
  scanf("%s", filename);
  printf("Number of Biggest Pages  :");
  scanf("%d", &npages);
  report_biggest_pages(tgf->gf, filename,npages);
  free(filename); filename = NULL;
}

void
generate_index_reports(mainFrame *mf)
{
  tgrFrame *tgf = (tgrFrame *)mf->cur_node_tgf->info;
  char * filename = malloc(50);
  int nbpages = 0;
  int nrpages = 0;
  if(!filename) {
      fprintf(stderr,"Out of Memory generate_index_reports\n");
      abort();
  }
  printf("Prefix for Reports : ");
  scanf("%s", filename);
  printf("Number of Biggest Pages  :");
  scanf("%d", &nbpages);
  printf("Number of Pages with Highest References  :");
  scanf("%d", &nrpages);
  report_index_of_reports(tgf->gf, filename,nbpages,nrpages);
  free(filename); filename = NULL;
}

void
generate_matrix_shortest_paths(mainFrame *mf)
{
  tgrFrame *tgf = (tgrFrame *)mf->cur_node_tgf->info;
  char * filename = malloc(50);
  if(!filename) {
      fprintf(stderr,"Out of Memory generate_matrix_shortest_paths\n");
      abort();
  }
  printf("File Name for Matrix: ");
  scanf("%s", filename);
  write_matrix_shortest_paths(tgf, filename);
  free(filename); filename = NULL;
}

void
execute_compute_cluster_coefficient(mainFrame *mf)
{
  tgrFrame *tgf = (tgrFrame *)mf->cur_node_tgf->info;
  double cc = 0;
  cc = compute_cluster_coefficient(tgf->gf);
  printf("Cluster Coefficient %f\n", cc);
}

int
execute_report_hierarchical_tree(mainFrame *mf)
{
  tgrFrame *tgf = (tgrFrame *)mf->cur_node_tgf->info;
  char * filename = malloc(50);
  int vnum=0;
  struct pt *v;
  int mes = -1;

  if(!filename) {
      fprintf(stderr,"Out of Memory execute_biggest_pages\n");
      abort();
  }

  printf("HTML File Name for report of Hierarchical Tree  :");
  scanf("%s", filename);
  printf("\nNumber of the Root Vertex : ");
  scanf("%d", &vnum);

  v = find_vertex_by_number(tgf->gf,vnum);
  if(v) 
      report_hierarchical_tree(tgf, filename,v);
  else
    printf("Vertex %d was not found\n", vnum);

  free(filename); filename = NULL;
  return mes;
}


void
execute_references_pages(mainFrame *mf)
{
  tgrFrame *tgf = (tgrFrame *)mf->cur_node_tgf->info;
  char * filename = malloc(50);
  int npages = 0;
  if(!filename) {
      fprintf(stderr,"Out of Memory execute_references_pages\n");
      abort();
  }

  printf("HTML File Name for report of Pages with Highest References  :");
  scanf("%s", filename);
  printf("Number of Pages  :");
  scanf("%d", &npages);
  report_references_pages(tgf->gf, filename,npages);
  free(filename); filename = NULL;
}

void
execute_images_no_alt(mainFrame *mf)
{
  tgrFrame *tgf = (tgrFrame *)mf->cur_node_tgf->info;
  char * filename = malloc(50);
  if(!filename) {
      fprintf(stderr,"Out of Memory execute_images_no_alt\n");
      abort();
  }

  printf("HTML File Name for report of images without alt :");
  scanf("%s", filename);
  report_ord_images_no_alt(tgf->gf, filename);
  free(filename); filename = NULL;
}

void
execute_pages_images_no_alt(mainFrame *mf)
{
  tgrFrame *tgf = (tgrFrame *)mf->cur_node_tgf->info;
  char * filename = malloc(50);
  if(!filename) {
      fprintf(stderr,"Out of Memory execute_pages_images_no_alt\n");
      abort();
  }

  printf("HTML File Name for report of Pages with images without alt :");
  scanf("%s", filename);
  report_ord_pages_images_no_alt(tgf->gf, filename);
  free(filename); filename = NULL;
}

void
execute_pages_broken_links(mainFrame *mf)
{
  tgrFrame *tgf = (tgrFrame *)mf->cur_node_tgf->info;
  char * filename = malloc(50);
  if(!filename) {
      fprintf(stderr,"Out of Memory execute_pages_broken_links\n");
      abort();
  }

  printf("HTML File Name for report of pages with broken links :");
  scanf("%s", filename);

  report_ord_pages_broken_links(tgf->gf, filename);
  free(filename); filename = NULL;
}

void
execute_report_hyperlinks(mainFrame *mf)
{
  tgrFrame *tgf = (tgrFrame *)mf->cur_node_tgf->info;
  char * filename = malloc(50);
  if(!filename) {
      fprintf(stderr,"Out of Memory execute_report_hyperlinks\n");
      abort();
  }

  printf("HTML File Name for report of Hyperlinks :");
  scanf("%s", filename);
  report_hyperlinks(tgf->gf, filename);
  free(filename); filename = NULL;
}

void
execute_broken_links(mainFrame *mf)
{
  tgrFrame *tgf = (tgrFrame *)mf->cur_node_tgf->info;
  char * filename = malloc(50);
  if(!filename) {
      fprintf(stderr,"Out of Memory execute_broken_links\n");
      abort();
  }

  printf("HTML File Name for report of broken links :");
  scanf("%s", filename);
  report_ord_broken_links(tgf->gf, filename);
  free(filename); filename = NULL;
}

void
execute_broken_objects(mainFrame *mf)
{
  tgrFrame *tgf = (tgrFrame *)mf->cur_node_tgf->info;
  char * filename = malloc(50);
  if(!filename) {
      fprintf(stderr,"Out of Memory execute_broken_objects\n");
      abort();
  }

  printf("HTML File Name for report of broken objects :");
  scanf("%s", filename);
  report_ord_broken_objects(tgf->gf, filename);
  free(filename); filename = NULL;
}

void
execute_pages_without_title(mainFrame *mf)
{
  tgrFrame *tgf = (tgrFrame *)mf->cur_node_tgf->info;
  char * filename = malloc(50);
  if(!filename) {
      fprintf(stderr,"Out of Memory execute_pages_without_title\n");
      abort();
  }

  printf("HTML File Name for report of pages without title :");
  scanf("%s", filename);
  report_ord_pages_without_title(tgf->gf, filename);
  free(filename); filename = NULL;
}

void
execute_report_pages(mainFrame *mf)
{
  tgrFrame *tgf = (tgrFrame *)mf->cur_node_tgf->info;
  char * filename = malloc(50);
  if(!filename) {
      fprintf(stderr,"Out of Memory execute_report_pages\n");
      abort();
  }

  printf("HTML File Name for report of Pages :");
  scanf("%s", filename);
  report_pages(tgf->gf, filename);
  free(filename); filename = NULL;
}

void
execute_web_directory(mainFrame *mf)
{
  tgrFrame *tgf = (tgrFrame *)mf->cur_node_tgf->info;
  char * filename = malloc(50);
  char * url_base = malloc(50);

  if(!filename) {
      fprintf(stderr,"Out of Memory execute_web_directory\n");
      abort();
  }
  if(!url_base) {
      fprintf(stderr,"Out of Memory execute_web_directory\n");
      abort();
  }
  printf("Graph File Name for Web Directory :");
  scanf("%s", filename);
  printf("URL base:");
  scanf("%s", url_base);
  construct_web_directory(mf,tgf,filename,url_base);
  free(filename);  free(url_base);
  filename = NULL; url_base = NULL;
}

void
execute_first_partition(mainFrame *mf)
{
  int mn=0, mt=0;
  char rep='n';
  
  printf("Minimum number of Nodes in a graph: ");
  scanf("%d",&mn);
  printf("Maximum number of Nodes in a Sub tree: ");
  scanf("%d",&mt);
  printf("Do you want HTML Report? (y/n) ");
  scanf("%c",&rep);
  scanf("%c",&rep);
  first_partition_algorithm(mf, mn, mt, rep);
}
void
execute_second_partition(mainFrame *mf)
{
  int mn=0, mt=0;
  char rep;

  printf("Minimum number of Nodes in a graph: ");
  scanf("%d",&mn);
  printf("Maximum number of Nodes in a Sub tree: ");
  scanf("%d",&mt);
  printf("Do you want HTML Report? (y/n) ");
  scanf("%c",&rep);
  scanf("%c",&rep);
  second_partition_algorithm(mf, mn, mt,rep);
}
void
execute_third_partition(mainFrame *mf)
{
  int mn=0, mt=0;
  char rep='n';
  
  printf("Minimum number of Nodes in a graph: ");
  scanf("%d",&mn);
  printf("Maximum number of Nodes in a Sub tree: ");
  scanf("%d",&mt);
  printf("Do you want HTML Report? (y/n) ");
  scanf("%c",&rep);
  scanf("%c",&rep);
  third_partition_algorithm(mf, mn, mt, rep);
}

void
execute_dir_clustering(mainFrame *mf)
{
  int mn=0;

  printf("Minimum number of Nodes in a graph: ");
  scanf("%d",&mn);

  /*dir_cluster_algorithm(mf,mn);*/
}

void
execute_dir_partition(mainFrame *mf)
{
  int mn=0;

  printf("Minimum number of Nodes in a graph: ");
  scanf("%d",&mn);

  dir_partition_algorithm(mf,mn);
}

tgrFrame *
execute_line_graph(mainFrame *mf)
{
  tgrFrame *tgf = (tgrFrame *)mf->cur_node_tgf->info;
  GraphFrame *gf = tgf->gf;
  GraphFrame *ngf; 
  tgrFrame *ntgf; 

  ngf = create_current_graph();
  ntgf = new_tgr_frame(ngf);

  init_graph(ngf);
  
  set_graph_dir(ngf,get_graph_dir(gf));
  set_num_ver_group(ngf,get_num_ver_group(gf));
  set_num_vertex(ngf,get_num_vertex(gf));
  set_dim_vertex(ngf,get_ver_size(gf),get_hor_size(gf));
  set_scale(ngf,get_scale(gf));
  set_dimensions(ngf,gf->w, gf->h);
  
  generate_line_graph(ngf,gf);

  Insert_linked_list(mf->ltgr_frame, create_new_node_llist((char *)ntgf));
  return ntgf;
}


void
execute_site_map(mainFrame *mf)
{
  tgrFrame *tgf = (tgrFrame *)mf->cur_node_tgf->info;
  int option=0;
  int is_last =0;
  int is_simple =0;
  struct pt *r = NULL;
  char * filename = malloc(50);
  if(!filename) {
      fprintf(stderr,"Out of Memory execute_site_map\n");
      abort();
  }
  printf("HTML File Name for Site Map :");
  scanf("%s", filename);
  printf("TABLE : 0  or LIST : 1 -> ");
  scanf("%d",&option);
  printf("Root is first node : 0 or last node : 1 -> ");
  scanf("%d",&is_last);
  printf("Complex: 0 or Simple : 1 -> ");
  scanf("%d",&is_simple);

  if(!is_last)
    r = get_first_vertex(tgf->gf);

  report_map_site(mf, tgf, filename,r,option,is_simple,0);

  free(filename); filename = NULL;
}



#define SHAPE_HTTP_HTML_DOC BOX
#define SHAPE_HTTP_ANY_DOC CIRCULAR
#define SHAPE_HTTP_DOC OCTAGON
#define SHAPE_FTP_DOC RHOMBUS
#define SHAPE_MAILTO_DOC HOR_ELLIPSIS
#define SHAPE_PROT_DOC VER_ELLIPSIS
#define SHAPE_BROKEN_DOC TRIANGLE

void
set_shape_from_attributes(GraphFrame *gf)
{
  LNode_type *ptr, *lv = get_list_vertices(gf);
  for(ptr = lv->back  ; ptr->back !=  lv ; ptr = ptr->back)
    {
      struct pt *v = (struct pt * )ptr->info;
      char *label = get_label_vertex(v);
      const char *mtype = get_attribute(v, "mime");
      const char *msize =get_attribute(v,"size");
      int size = msize ? atoi(msize) : -1;
      const char *mcode =get_attribute(v,"code");
      int code = mcode ? atoi(mcode) : -1;

       if(!strncmp(label,"http://",7))
	 {
	   if(mtype && !strcmp(mtype,"text/html"))
	     set_vertex_shape(v,SHAPE_HTTP_HTML_DOC);
	   else if(size >=0)
	     set_vertex_shape(v,SHAPE_HTTP_ANY_DOC);
	   else
	     set_vertex_shape(v,SHAPE_HTTP_DOC);
	 }
       else if(!strncmp(label,"ftp://",6))
	 set_vertex_shape(v,SHAPE_FTP_DOC);
       else if(!strncmp(label,"mailto:",7))
	 set_vertex_shape(v,SHAPE_MAILTO_DOC);
       else
	 set_vertex_shape(v,SHAPE_PROT_DOC);

       if(code > 400)
	 set_vertex_shape(v,SHAPE_BROKEN_DOC);
    }
}

